
package sbc.jms;

import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Properties;
import javax.jms.JMSException;
import javax.jms.ObjectMessage;
import javax.jms.Queue;
import javax.jms.QueueConnection;
import javax.jms.QueueConnectionFactory;
import javax.jms.QueueReceiver;
import javax.jms.QueueSender;
import javax.jms.QueueSession;
import javax.jms.Session;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import sbc.fabrik.model.Employee;
import sbc.fabrik.model.Platine;
import sbc.fabrik.model.Sensor;




public class Manufacturer extends Employee {
    
    QueueConnectionFactory  queueConnectionFactory = null;
    QueueConnection queueConnection = null;
    QueueSession queueSession = null;
    Queue queue = null;
    
    public Manufacturer(int id) {
        super(id);
        
        Context jndiContext = null;
        
        
        try {
            Properties properties = new Properties();
            properties.put(Context.INITIAL_CONTEXT_FACTORY, "org.jnp.interfaces.NamingContextFactory");
            properties.put(Context.URL_PKG_PREFIXES, "org.jnp.interfaces");
            properties.put(Context.PROVIDER_URL, "localhost");
            
            jndiContext = new InitialContext(properties);
            
            queueConnectionFactory = (QueueConnectionFactory) jndiContext.lookup("ConnectionFactory");
            queue = (Queue) jndiContext.lookup("queue/sbc");
            
        } catch (NamingException e) {System.out.println("JNDI lookup failed: " + e.toString());
        e.printStackTrace();
        System.exit(1);
        }
        
    }
    
    public void work() {
        try {
            ObjectMessage             message = null;
            
            
            queueConnection = queueConnectionFactory.createQueueConnection();
            QueueSession session = (QueueSession)  queueConnection.createQueueSession(false, Session.AUTO_ACKNOWLEDGE);
            QueueReceiver ModulSubscriber = session.createReceiver(queue, "ModulType = '" + Platine.class.getCanonicalName()
            + "' OR (ModulType = '" + Sensor.class.getCanonicalName() +  "' AND Inspected = true)");
            QueueReceiver PlatineSubscriber =  session.createReceiver(queue,"ModulType = '" +  Platine.class.getCanonicalName() + "'");
            QueueReceiver SensorSubscriber =  session.createReceiver(queue,"ModulType = '" + Sensor.class.getCanonicalName() + "' AND Inspected = true");
           
            QueueSender PlatineSender = session.createSender(queue);
            queueConnection.start();
            System.out.println("receiving...");
            
            
            
            QueueReceiver Subscriber = ModulSubscriber;
            Platine platine = null;
            ArrayList sensorList = new ArrayList();
            
            do {
                ObjectMessage modul =  (ObjectMessage) Subscriber.receive();
                //System.out.println(modul);
                //System.out.println(modul.getClass().getCanonicalName());
                if ( modul.getStringProperty("ModulType").contentEquals(Platine.class.getCanonicalName())) {
                    //System.out.println("platine");
                    platine = (Platine) modul.getObject();
                    System.out.println("RAW: " + platine);
                    Subscriber = SensorSubscriber;
                }
                if ( modul.getStringProperty("ModulType").contentEquals(Sensor.class.getCanonicalName())) {
                    //System.out.println("Sensor" + sensorList.size());
                    if (sensorList.size() < 2) sensorList.add((Sensor) modul.getObject());
                }
                
                
            } while ((platine == null) || (sensorList.size() < 2)) ;
            
            platine.setSensors(sensorList);
            System.out.println("OUT: " + platine);
            // write back platine to topic!
            ObjectMessage outMsg = session.createObjectMessage();
            outMsg.setStringProperty("ModulType", platine.getClass().getCanonicalName());
            outMsg.setBooleanProperty("Completed", true);
            outMsg.setObject(platine);
            //System.out.println("SENDING*************" + outMsg);
            PlatineSender.send(outMsg);
            
            System.out.println("**************************************************");
            
            
            
        } catch (JMSException e) {
            System.out.println("Exception occurred: " +
                    e.toString());
        } finally {
            if (queueConnection != null) {
                try {
                    queueConnection.close();
                } catch (JMSException e) {}
            }
        }
        
    }
    
    /**
     * Main method.
     *
     * @param args     the topic used by the example
     */
    public static void main(String[] args) {
        InputStreamReader       inputStreamReader = null;
        char                    answer = '\0';
        
        Manufacturer mano = new Manufacturer(Integer.parseInt(args[0]));
        
        System.out.println("To end program, enter Q or q, " +
                "then <return>");
        inputStreamReader = new InputStreamReader(System.in);
        while (!((answer == 'q') || (answer == 'Q'))) {
            mano.work();
        }
        try {
            answer = (char) inputStreamReader.read();
        } catch (IOException e) {
            System.out.println("I/O exception: "
                    + e.toString());
        }
        
        
    }
    
}
